
#include <cegfx/cephysics.h>
#include <cegfx/cemotionstate.h>


cePhysics::cePhysics ()
	: config(0)
	, dispatcher(0)
	, broadphase(0)
	, solver(0)
	, world(0)
{
	IQF_CONSTRUCT;
}

cePhysics::~cePhysics ()
{
}

IQF_IMPLEMENTATION_BEGIN(cePhysics);
IQF_IMPLEMENTATION_END();

void cePhysics::Initialize (const D3DXVECTOR3& gravity)
{
	config = new btDefaultCollisionConfiguration();
	dispatcher = new btCollisionDispatcher (config);
	broadphase = new btDbvtBroadphase ();
	solver = new btSequentialImpulseConstraintSolver ();
	world = new btDiscreteDynamicsWorld (dispatcher, broadphase, solver, config);

	world->setGravity (btVector3 (gravity.x, gravity.y, gravity.z));
}

void cePhysics::Step (float time)
{
	world->stepSimulation (time);
}



btRigidBody* cePhysics::AddStatic (btCollisionShape* shape,
																	 const D3DXVECTOR3& position,
																	 float angle,
																	 const D3DXVECTOR3& axis)
{
	btVector3 inertia (0, 0, 0);

	// create the rigid body for the static physics
	btRigidBody::btRigidBodyConstructionInfo rbInfo(0.0f, 0, shape, inertia);
	btRigidBody* body = new btRigidBody(rbInfo);

	btTransform tr;
	tr.setOrigin(btVector3 (position.x, position.y, position.z));
	tr.setRotation (btQuaternion(btVector3 (axis.x, axis.y, axis.z), angle));
	body->setWorldTransform (tr);


	world->addRigidBody (body);
	return body;
}


btRigidBody* cePhysics::AddDynamic (btCollisionShape* shape, 
																		ceNode*						node,
																		float							mass)
{
	btVector3 inertia (0, 0, 0);
	shape->calculateLocalInertia (mass, inertia);

	ceMotionState* ms = new ceMotionState (node);

	// create the rigid body for the static physics
	btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, ms, shape, inertia);
	btRigidBody* body = new btRigidBody(rbInfo);

	world->addRigidBody (body);

	body->setUserPointer (node);
	return body;
}
